Содержание

  • 1  Открытие файла и изучение общей информации
  • 2  Предобработка данных
    • 2.1  Изменение типов данных
    • 2.2  Работа с пропусками
    • 2.3  Работа с дубликатами
    • 2.4  Работа со значениями
    • 2.5  Подсчет суммарных продаж
    • 2.6  Вывод
  • 3  Исследовательский анализ
    • 3.1  Количество выпущенных игр в год
    • 3.2  Распределение продаж на платформах с наибольшими суммарными продажами по годам
    • 3.3  Распределение продаж на актуальных платформах по годам
    • 3.4  Разброс продаж на актуальных платформах
    • 3.5  Зависимость продаж от оценок критиков и пользователей
    • 3.6  Анализ игр по жанрам
    • 3.7  Вывод
  • 4  Портрет пользователя каждого региона
    • 4.1  Популярность платформ по регионам
    • 4.2  Популярность жанров по регионам
    • 4.3  Влияние возрастного рейтинга на продажи в регионах
    • 4.4  Вывод
  • 5  Проверка гипотез
    • 5.1  Пользовательские рейтинги платформ Xbox One и PC
    • 5.2  Пользовательские рейтинги жанров Action и Sports
  • 6  Общий вывод

Исследование о продажах и рейтингах видеоигр¶

Из открытых источников доступны исторические данные о продажах игр, оценки пользователей и экспертов, жанры и платформы. Необходимо выявить определяющие успешность игры закономерности. Это позволит сделать ставку на потенциально популярный продукт и спланировать рекламные кампании. Представим, что сейчас декабрь 2016 года, нужно спланировать рекламную кампанию на 2017 год.

Открытие файла и изучение общей информации¶

In [1]:
import pandas as pd
import plotly.express as px
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats as st

import warnings
warnings.filterwarnings('ignore')
In [2]:
try:
    games = pd.read_csv('/datasets/games.csv')
except:
    games = pd.read_csv('games.csv')
In [3]:
games.head()
Out[3]:
Name Platform Year_of_Release Genre NA_sales EU_sales JP_sales Other_sales Critic_Score User_Score Rating
0 Wii Sports Wii 2006.0 Sports 41.36 28.96 3.77 8.45 76.0 8 E
1 Super Mario Bros. NES 1985.0 Platform 29.08 3.58 6.81 0.77 NaN NaN NaN
2 Mario Kart Wii Wii 2008.0 Racing 15.68 12.76 3.79 3.29 82.0 8.3 E
3 Wii Sports Resort Wii 2009.0 Sports 15.61 10.93 3.28 2.95 80.0 8 E
4 Pokemon Red/Pokemon Blue GB 1996.0 Role-Playing 11.27 8.89 10.22 1.00 NaN NaN NaN
In [4]:
games.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 16715 entries, 0 to 16714
Data columns (total 11 columns):
 #   Column           Non-Null Count  Dtype  
---  ------           --------------  -----  
 0   Name             16713 non-null  object 
 1   Platform         16715 non-null  object 
 2   Year_of_Release  16446 non-null  float64
 3   Genre            16713 non-null  object 
 4   NA_sales         16715 non-null  float64
 5   EU_sales         16715 non-null  float64
 6   JP_sales         16715 non-null  float64
 7   Other_sales      16715 non-null  float64
 8   Critic_Score     8137 non-null   float64
 9   User_Score       10014 non-null  object 
 10  Rating           9949 non-null   object 
dtypes: float64(6), object(5)
memory usage: 1.4+ MB

Описание колонок:

  • Name — название игры
  • Platform — платформа
  • Year_of_Release — год выпуска
  • Genre — жанр игры
  • NA_sales — продажи в Северной Америке (миллионы проданных копий)
  • EU_sales — продажи в Европе (миллионы проданных копий)
  • JP_sales — продажи в Японии (миллионы проданных копий)
  • Other_sales — продажи в других странах (миллионы проданных копий)
  • Critic_Score — оценка критиков (максимум 100)
  • User_Score — оценка пользователей (максимум 10)
  • Rating — рейтинг от организации ESRB (англ. Entertainment Software Rating Board). Эта ассоциация определяет рейтинг компьютерных игр и присваивает им подходящую возрастную категорию.

Посмотрим количество явных дубликатов

In [5]:
games.duplicated().sum()
Out[5]:
0

Явные дубликаты отсутствуют

Неявные дубликаты обработаем в разделе "Предобработка данных".

In [6]:
games.hist(figsize=(8, 8))
Out[6]:
array([[<AxesSubplot:title={'center':'Year_of_Release'}>,
        <AxesSubplot:title={'center':'NA_sales'}>],
       [<AxesSubplot:title={'center':'EU_sales'}>,
        <AxesSubplot:title={'center':'JP_sales'}>],
       [<AxesSubplot:title={'center':'Other_sales'}>,
        <AxesSubplot:title={'center':'Critic_Score'}>]], dtype=object)

По гистограммам можно говорить о том, что игры чаще выпускались после 2000 года, а критики чаще всего ставили оценки 65-70.

In [7]:
games.isna().sum()
Out[7]:
Name                  2
Platform              0
Year_of_Release     269
Genre                 2
NA_sales              0
EU_sales              0
JP_sales              0
Other_sales           0
Critic_Score       8578
User_Score         6701
Rating             6766
dtype: int64
In [8]:
def pass_value_barh(data):
    try:
        (
            (data.isna().mean()*100)
            .to_frame()
            .rename(columns = {0: 'space'})
            .query('space > 0')
            .sort_values(by='space', ascending=True)
            .plot(kind='barh', figsize=(8, 6), rot=.5, legend=False, fontsize=12)
            .set_title('Пропуски в данных, %', fontsize=16, color='SteelBlue')
        )
    except:
        print('Пропусков нет')
In [9]:
pass_value_barh(games)

В датасете имеется довольно большое количество пропусков. Рассмотрим их ниже.

В данной части был прочитан файл с данными и просмотрены основные сведения о датесете. Далее необходимо разобраться с пропущенными значениями, дубликатами, а также подсчитать суммарные продажи.

Предобработка данных¶

Приведем названия колонок к нижнему регистру

In [10]:
games.columns = [col.lower().replace(' ', '_') for col in games.columns]

Изменение типов данных¶

Рассмотрим типы данных в колонках

In [11]:
games.dtypes
Out[11]:
name                object
platform            object
year_of_release    float64
genre               object
na_sales           float64
eu_sales           float64
jp_sales           float64
other_sales        float64
critic_score       float64
user_score          object
rating              object
dtype: object

Можно поменять типы данных в колонках:

  • year с float на int (год выпуска не может быть дробным)
  • critic_score с float на int (оценка ставится по 100-больной шкале)
  • user_score с object на float (оценка ставится по 10-больной шкале (включая дробные оценки), однако есть игры, оценка которых еще не проставлена. Такое поле заполнено значением tbd - будет определено. Следовательно можно произвести замену tbd на NaN)
In [12]:
games.year_of_release = games.year_of_release.astype('Int64')
In [13]:
games.critic_score = games.critic_score.astype('Int64')

Значение tbd в колонке user_score можно рассмотреть подробнее:

In [14]:
games.query('user_score == "tbd"').groupby('year_of_release')['name'].count()
Out[14]:
year_of_release
1997      1
1999      8
2000     43
2001     82
2002    192
2003     95
2004    107
2005    121
2006    124
2007    192
2008    326
2009    405
2010    331
2011    217
2012     24
2013     15
2014     21
2015     38
2016     34
Name: name, dtype: int64

Значение tbd в колонке user_score сконцентрированы с 2004 по 2011 года. Можно сделать следующие предположения:

  • пользовательский рейтинг пока еще не указан в самом источнике данных
  • пользовательский рейтинг еще не подсчитали (если он считался не с одного источника, а с нескольких)
  • сама игра прошла совершенно незамеченной, и официальный рейтинг игры будет очень сложно найти

Думаю, что лучше всего будет заменить tbd на NaN, далее просто поменять тип данных в колонке.

In [15]:
games.user_score = games.user_score.replace('tbd', np.nan).astype('float64')

Работа с пропусками¶

In [16]:
games.isna().sum()
Out[16]:
name                  2
platform              0
year_of_release     269
genre                 2
na_sales              0
eu_sales              0
jp_sales              0
other_sales           0
critic_score       8578
user_score         9125
rating             6766
dtype: int64

Имеются пропуски в колонках:

  • name - название игры
  • year_of_release - год выпуска игры
  • genre - жанр игры
  • critic_score - оценка критиков
  • user_score - оценка пользователей

Рассмотрим пропуски в колонке name:

In [17]:
games[games['name'].isnull()]
Out[17]:
name platform year_of_release genre na_sales eu_sales jp_sales other_sales critic_score user_score rating
659 NaN GEN 1993 NaN 1.78 0.53 0.00 0.08 <NA> NaN NaN
14244 NaN GEN 1993 NaN 0.00 0.00 0.03 0.00 <NA> NaN NaN

Строки с пропусками с колонке name можно удалить. Их мало, следовательно, они ни на что не повлияют

In [18]:
games = games[games['name'].notna()]

Рассмотрим пропуски в колонке year_of_release:

Сначала стоит посмотреть, имеются ли в датасете мультиплатформенные игры:

In [19]:
games.pivot_table(index='name', values='platform', aggfunc='count').reset_index().query('platform > 1')
Out[19]:
name platform
2 Frozen: Olaf's Quest 2
17 007: Quantum of Solace 6
18 007: The World is not Enough 2
33 11eyes: CrossOver 2
39 18 Wheeler: American Pro Trucker 2
... ... ...
11544 iCarly 2
11545 iCarly 2: iJoin The Click! 2
11549 nail'd 2
11550 pro evolution soccer 2011 6
11556 uDraw Studio: Instant Artist 2

2805 rows × 2 columns

Такие игры имеются (2805 игр). Год релиза на другие платформы чаще всего несильно отличается/не отличается совсем от года релиза на основную платформу (исключения есть для игр, которые переиздаются на консоли следующего поколения). Также и оценки чаще всего несильно отличаются у мультиплатформенных игр. Однако лучше не рисковать и не трогать пропуски (и год релиза, и оценки могут сильно отличаться от платформы к платформе). Строки с пропусками в колонке год издания можно удалить. Строки с пропусками в оценках лучше оставить.

In [20]:
games = games[games['year_of_release'].notna()]

Рейтинг игры также может отличаться от платформы к платформе. Например, в игре Need for Speed: Most Wanted:

In [21]:
games.query('name == "Need for Speed: Most Wanted"')
Out[21]:
name platform year_of_release genre na_sales eu_sales jp_sales other_sales critic_score user_score rating
253 Need for Speed: Most Wanted PS2 2005 Racing 2.03 1.79 0.08 0.47 82 9.1 T
523 Need for Speed: Most Wanted PS3 2012 Racing 0.71 1.46 0.06 0.58 <NA> NaN NaN
1190 Need for Speed: Most Wanted X360 2012 Racing 0.62 0.78 0.01 0.15 83 8.5 T
1591 Need for Speed: Most Wanted X360 2005 Racing 1.00 0.13 0.02 0.10 83 8.5 T
1998 Need for Speed: Most Wanted XB 2005 Racing 0.53 0.46 0.00 0.05 83 8.8 T
2048 Need for Speed: Most Wanted PSV 2012 Racing 0.33 0.45 0.01 0.22 <NA> NaN NaN
3581 Need for Speed: Most Wanted GC 2005 Racing 0.43 0.11 0.00 0.02 80 9.1 T
5972 Need for Speed: Most Wanted PC 2005 Racing 0.02 0.23 0.00 0.04 82 8.5 T
6273 Need for Speed: Most Wanted WiiU 2013 Racing 0.13 0.12 0.00 0.02 <NA> NaN NaN
6410 Need for Speed: Most Wanted DS 2005 Racing 0.24 0.01 0.00 0.02 45 6.1 E
6473 Need for Speed: Most Wanted GBA 2005 Racing 0.19 0.07 0.00 0.00 <NA> 8.3 E
11715 Need for Speed: Most Wanted PC 2012 Racing 0.00 0.06 0.00 0.02 82 8.5 T

Пропуски в колонке rating возникают из-за того, что ассоциация ESRB (Entertainment Software Rating Board) не выставила рейтинг игре. Это могло произойти по нескольким причинам:

  • игра была отменена еще до релиза
  • игра прошла незамеченной и ESRB просто не тратит время на такие игры
  • ESRB просто не успела выставить рейтинг игре.

Также все имеющиеся пропуски могли возникнуть как по причине ошибки при выгрузке данных, так и по причине отсутствия этих данных в источниках.

In [22]:
games.isna().sum()
Out[22]:
name                  0
platform              0
year_of_release       0
genre                 0
na_sales              0
eu_sales              0
jp_sales              0
other_sales           0
critic_score       8461
user_score         8981
rating             6676
dtype: int64

Работа с дубликатами¶

Для работы в неявными дубликатами лучше рассматривать связку Название - Платформа - Год издания, чтоб исключить переиздания из дубликатов.

In [23]:
games.duplicated(subset=['name', 'platform', 'year_of_release']).sum()
Out[23]:
1

В датасете есть один дубликат:

In [24]:
games[games.duplicated(subset=['name', 'platform', 'year_of_release'], keep=False)]
Out[24]:
name platform year_of_release genre na_sales eu_sales jp_sales other_sales critic_score user_score rating
604 Madden NFL 13 PS3 2012 Sports 2.11 0.22 0.0 0.23 83 5.5 E
16230 Madden NFL 13 PS3 2012 Sports 0.00 0.01 0.0 0.00 83 5.5 E

Просуммируем продажи между собой:

In [25]:
games[['na_sales', 
       'eu_sales', 
       'jp_sales', 
       'other_sales']] = (games
                          .groupby(['name', 'platform', 'year_of_release'])['na_sales',
                                                                            'eu_sales',
                                                                            'jp_sales', 
                                                                            'other_sales']
                          .transform('sum'))

Проверка суммы:

In [26]:
games[games.duplicated(subset=['name', 'platform', 'year_of_release'], keep=False)]
Out[26]:
name platform year_of_release genre na_sales eu_sales jp_sales other_sales critic_score user_score rating
604 Madden NFL 13 PS3 2012 Sports 2.11 0.23 0.0 0.23 83 5.5 E
16230 Madden NFL 13 PS3 2012 Sports 2.11 0.23 0.0 0.23 83 5.5 E

Проверка количества записей до удаления:

In [27]:
games.shape[0]
Out[27]:
16444

Удаляем дубликаты:

In [28]:
games = games.drop_duplicates(subset=['name', 'platform', 'year_of_release'])

Проверка количества записей после удаления:

In [29]:
games.shape[0]
Out[29]:
16443
In [30]:
games.duplicated(subset=['name', 'platform', 'year_of_release']).sum()
Out[30]:
0

Работа со значениями¶

Рассмотрим подробнее колонку rating:

In [31]:
games.rating.value_counts(dropna=False)
Out[31]:
NaN     6676
E       3920
T       2905
M       1536
E10+    1393
EC         8
K-A        3
AO         1
RP         1
Name: rating, dtype: int64

Рейтинги означают следующее:

  • E - "Для всех"
  • T - "Подросткам"
  • M - "Для взрослых"
  • E10+ - "Для всех от 10 лет и старше"
  • EC - "Для детей младшего возраста"
  • K-A - "Для всех" (первоначальный вариант категории E, следовательно можно заменить на E)
  • AO - "Только для взрослых"
  • RP - "Рейтинг ожидается" (ставится до официального релиза игры. Может присутствовать в датасете из-за предзаказов или отменённой игры. Можно заменить на NaN)
In [32]:
games.rating = games.rating.replace({'K-A': 'E', 'RP': None})

Подсчет суммарных продаж¶

Посчитаем суммарные продажи по всем регионам:

In [33]:
games.insert(loc=games.columns.get_loc('critic_score'),
                        column='total_sales', value=round(games.loc[:, 'na_sales':'other_sales'].sum(axis=1), 3))

games.head()
Out[33]:
name platform year_of_release genre na_sales eu_sales jp_sales other_sales total_sales critic_score user_score rating
0 Wii Sports Wii 2006 Sports 41.36 28.96 3.77 8.45 82.54 76 8.0 E
1 Super Mario Bros. NES 1985 Platform 29.08 3.58 6.81 0.77 40.24 <NA> NaN NaN
2 Mario Kart Wii Wii 2008 Racing 15.68 12.76 3.79 3.29 35.52 82 8.3 E
3 Wii Sports Resort Wii 2009 Sports 15.61 10.93 3.28 2.95 32.77 80 8.0 E
4 Pokemon Red/Pokemon Blue GB 1996 Role-Playing 11.27 8.89 10.22 1.00 31.38 <NA> NaN NaN

Вывод¶

В данном разделе было выполнено следующее:

  • изменены типы данных (на подходящие)
  • обработаны пропуски
  • обработаны неявные дубликаты
  • посчитаны суммарные продажи для каждой игры по всем регионам

Исследовательский анализ¶

Количество выпущенных игр в год¶

Рассмотрим подробнее, сколько игр выпускалось в разные года:

In [34]:
games.year_of_release.hist(bins=36)
plt.title("Количество выпущенных игр по годам \n", fontsize=16)
plt.xlabel('Год', fontsize=12)
plt.ylabel('Количество игр', fontsize=12)
plt.show()

По гистограмме можно заметить, что в целом наблюдается тенденция на увеличение числа выпущенных игр в год (возможно в выгрузку попало не так много данных с 2010 по 2014 года). Нам не так сильно важны данные до 2005 года. Так как запросы аудитории меняются (число игроков увеличивается, поколения сменяют друг друга), то возможно нам стоит рассматривать данные начиная с 2008, 2009 или 2010 года.

Распределение продаж на платформах с наибольшими суммарными продажами по годам¶

Рассмотрим, как менялись продажи по платформам:

Найдем топ-10 платформ, лидирующих по продажам за всё время

In [35]:
# находим топ-10 популярных платформ
platform_total_pivot = (games.pivot_table(index='platform', values='total_sales', aggfunc='sum')
                        .reset_index().sort_values('total_sales', ascending=False).set_index('platform').head(10))
platform_total_pivot
Out[35]:
total_sales
platform
PS2 1233.56
X360 961.24
PS3 931.34
Wii 891.18
DS 802.78
PS 727.58
PS4 314.14
GBA 312.88
PSP 289.53
3DS 257.81

Первые 3 позиции занимают:

  • PlayStation 2
  • XBox 360
  • PlayStation 3
In [36]:
platform_pivot = games.pivot_table(index='platform',
                                   columns='year_of_release', 
                                   values='total_sales', 
                                   aggfunc='sum').reset_index().rename_axis(None, axis=1).set_index('platform')
platform_pivot = platform_pivot[platform_pivot.index.isin(platform_total_pivot.index)].T.loc[1994:,:]
# в 1994 на платформах с самыми высокими продажами появляются первые релизы. Данные до 1994 года нам не нужны
In [37]:
fig = px.imshow(platform_pivot.T, labels={'y': 'Платформа',
                                                 'x': 'Год',
                                                 'color': 'Продажи, млн копий'},
                title="Распределение продаж на разных платформах по годам")
fig.show()

По графикам можно говорить о том, что средний "срок жизни" платформы составляет от 7 до 10 лет

Лучше взять данные с 2013 года для проведения дальнейшего анализа.

In [38]:
games_2013 = games.copy(deep=True).query('year_of_release >= 2013')

Распределение продаж на актуальных платформах по годам¶

Изучим продажи на разных платформах:

In [39]:
platform_2013_pivot = (games_2013
                       .pivot_table(index='platform', values='total_sales', aggfunc='sum')
                       .reset_index()
                       .sort_values('total_sales',ascending=False)
                       .set_index('platform'))
platform_2013_pivot = games_2013.pivot_table(index='platform',
                                   columns='year_of_release', 
                                   values='total_sales', 
                                   aggfunc='sum').reset_index().rename_axis(None, axis=1)
platform_2013_pivot
Out[39]:
platform 2013 2014 2015 2016
0 3DS 56.57 43.76 27.78 15.14
1 DS 1.54 NaN NaN NaN
2 PC 12.38 13.28 8.52 5.25
3 PS3 113.25 47.76 16.82 3.60
4 PS4 25.99 100.00 118.90 69.25
5 PSP 3.14 0.24 0.12 NaN
6 PSV 10.59 11.90 6.25 4.25
7 Wii 8.59 3.75 1.14 0.18
8 WiiU 21.65 22.03 16.35 4.60
9 X360 88.58 34.74 11.96 1.52
10 XOne 18.96 54.07 60.14 26.15

Можно исключить платформы, у которых нет данных по продажам за 2015 и 2016 года, т.к. эти платформы уже устарели. (для исследования тенденций в игровых жанрах эти платформы лучше оставить)

In [40]:
platform_2013_pivot = (platform_2013_pivot[~(platform_2013_pivot[2015].isna() & platform_2013_pivot[2016].isna())]
                       .set_index('platform'))
In [41]:
fig = px.imshow(platform_2013_pivot, labels={'y': 'Платформа',
                                                 'x': 'Год',
                                                 'color': 'Продажи, млн копий'},
                title="Распределение продаж на разных платформах по годам", aspect='auto')
fig.update_xaxes(type='category')

fig.layout.width = 600
fig.show()

Потенциально прибыльными платформами являются PlayStation 4 и XBox One, однако стоит делать ставку именно на PlayStation 4.

Разброс продаж на актуальных платформах¶

In [42]:
fig = px.box(games_2013, 
             x="platform", y="total_sales", color='platform', custom_data=['platform', 'total_sales', 'name'], 
             labels={'platform': 'Платформа', 
               'total_sales': 'Продажи, млн копий',
               'name': 'Название'},
            title='Разброс продаж на актуальных платформах')
fig.update_traces(
    hovertemplate="<br>".join([
        "Платформа: %{customdata[0]}",
        "Название: %{customdata[2]}",
        "Продажи, млн копий: %{customdata[1]}",
    ])
)
fig.update_xaxes(type='category')
fig.update_yaxes(range=[0, 1])
fig.show()

У большинства игр (вне зависимости от платформы) продажи не превышают ~ 0.8 млн копий. Медиана продаж не превышает ~0.27 млн копий. Однако она сильно колеблется от платформы к платформе
Самые большие продажи у игры PlayStation 3 и XBox 360. Но срок жизни этих платформ подходит к концу, следовательно, лучше смотреть платформы, которые следуют за ними. Это PlayStation 4, Nintendo 3DS и XBox One

Зависимость продаж от оценок критиков и пользователей¶

Посмотрим, как влияют на продажи внутри одной популярной платформы отзывы пользователей и критиков. Построим диаграмму рассеяния и посчитаем корреляцию между отзывами и продажами.

In [43]:
fig = px.scatter(games_2013, x="user_score", y="total_sales", color="platform",
                labels={'user_score': 'Оценка пользователей',
                        'total_sales': 'Продажи, млн копий',
                        'platform': 'Платформа'},
                 title="Зависимость продаж от оценки пользователей")
fig.show()
In [44]:
(games_2013
 .groupby('platform')[['user_score', 'total_sales']]
 .corr().reset_index().query('user_score < 1')
 .drop({'level_1', 'total_sales'}, axis=1).sort_values('user_score', ascending=False))
Out[44]:
platform user_score
15 Wii 0.682942
17 WiiU 0.419330
1 3DS 0.241504
7 PS3 0.002394
13 PSV 0.000942
19 X360 -0.011742
9 PS4 -0.031957
21 XOne -0.068925
5 PC -0.093842
11 PSP -1.000000
In [45]:
games_2013.user_score.corr(games_2013.total_sales)
Out[45]:
-0.002607813354598267

Оценки пользователей корреляции с продажами не имеют

In [46]:
fig = px.scatter(games_2013.query('critic_score.notna()'), x="critic_score", y="total_sales", color="platform",
                 labels={'critic_score': 'Оценка критиков',
                        'total_sales': 'Продажи, млн копий',
                        'platform': 'Платформа'},
                 title="Зависимость продаж от оценки критиков")
fig.show()
In [47]:
(games_2013
 .groupby('platform')[['critic_score', 'total_sales']]
 .corr().reset_index().query('critic_score < 1')
 .drop({'level_1', 'total_sales'}, axis=1).sort_values('critic_score', ascending=False))
Out[47]:
platform critic_score
21 XOne 0.416998
9 PS4 0.406568
17 WiiU 0.376415
1 3DS 0.357057
19 X360 0.350345
7 PS3 0.334285
13 PSV 0.254742
5 PC 0.196030
In [48]:
games_2013.critic_score.astype('float64').corr(games_2013.total_sales)
Out[48]:
0.3136995151027369

Оценки критиков демонстрируют прямую, слабую корреляцию с "цифрами" продаж (сильнее, чем оценки пользователей)

Анализ игр по жанрам¶

Посмотрим на общее распределение игр по жанрам

In [49]:
genre_2013_pivot = (games_2013.pivot_table(index='genre', values='total_sales', aggfunc=['count', 'sum', 'median'])
                    .reset_index())
genre_2013_pivot.columns = ['genre', 'count', 'sum', 'median']
genre_2013_pivot['sum'] = genre_2013_pivot['sum'].round(3)

fig = px.bar(genre_2013_pivot, x='genre', y='count',
             hover_data=['sum'], color='sum',
            labels={'genre': 'Жанр', 
                    'count': 'Количество игр',
                   'sum': 'Суммарные продажи'},
             title="Распредение количества игр по жанрам")
fig.update_layout(xaxis={'categoryorder': 'total descending'})

fig.show()

Рассмотрим медианные значения продаж по жанрам.

In [50]:
fig = px.bar(genre_2013_pivot, x='genre', y='median',
             hover_data=['sum'], color='sum',
            labels={'genre': 'Жанр', 
                    'count': 'Медианное значение продаж',
                   'sum': 'Суммарные продажи'},
             title="Распредение медианного количества продаж по жанрам")
fig.update_layout(xaxis={'categoryorder': 'total descending'})
fig.show()

Стоит чуть подробнее рассмотреть жанр Action, т.к. он заметно просел.

In [51]:
games_2013.query('genre == "Action"').sort_values('total_sales', ascending=False).head(10)
Out[51]:
name platform year_of_release genre na_sales eu_sales jp_sales other_sales total_sales critic_score user_score rating
16 Grand Theft Auto V PS3 2013 Action 7.02 9.09 0.98 3.96 21.05 97 8.2 M
23 Grand Theft Auto V X360 2013 Action 9.66 5.14 0.06 1.41 16.27 97 8.1 M
42 Grand Theft Auto V PS4 2014 Action 3.96 6.31 0.38 1.97 12.62 97 8.3 M
149 The Last of Us PS3 2013 Action 2.41 2.18 0.28 0.99 5.86 95 9.1 M
165 Grand Theft Auto V XOne 2014 Action 2.81 2.19 0.00 0.47 5.47 97 7.9 M
225 The Last of Us PS4 2014 Action 1.88 2.00 0.07 0.77 4.72 <NA> NaN NaN
231 Uncharted: The Nathan Drake Collection PS4 2015 Action 2.07 1.71 0.08 0.76 4.62 86 8.1 T
235 Luigi's Mansion: Dark Moon 3DS 2013 Action 1.80 1.39 1.11 0.29 4.59 86 8.4 E
295 Watch Dogs PS4 2014 Action 1.40 1.90 0.11 0.64 4.05 80 6.3 M
304 Assassin's Creed: Unity PS4 2014 Action 1.19 2.07 0.08 0.62 3.96 70 4.9 M
In [52]:
games_2013.query('name == "Grand Theft Auto V"').sort_values('total_sales', ascending=False)
Out[52]:
name platform year_of_release genre na_sales eu_sales jp_sales other_sales total_sales critic_score user_score rating
16 Grand Theft Auto V PS3 2013 Action 7.02 9.09 0.98 3.96 21.05 97 8.2 M
23 Grand Theft Auto V X360 2013 Action 9.66 5.14 0.06 1.41 16.27 97 8.1 M
42 Grand Theft Auto V PS4 2014 Action 3.96 6.31 0.38 1.97 12.62 97 8.3 M
165 Grand Theft Auto V XOne 2014 Action 2.81 2.19 0.00 0.47 5.47 97 7.9 M
1730 Grand Theft Auto V PC 2015 Action 0.39 0.69 0.00 0.09 1.17 96 7.9 M

В топе есть заметный лидер - Grand Theft Auto V. Эта игра в какой-то степени помогла выбраться вперед жанру Action. Это обусловлено несколькими причинами:

  • игру долго ждали
  • в качестве бесплатного дополнения к игре идет мультиплеерный режим (желающих играть вместе с другими игроками было достаточно)

Рейтинг игр всё-таки лучше составить не по полному значению продаж, а по медианному, т.к. так можно найти жарны, приносящие стабильный доход.

Топ-3 жанра по количеству игр:

  • Action
  • Misc
  • Sports

Тор-3 жанра по продажам:

  • Shooter
  • Sports
  • Platform

Жанр Action сильно выделяется как по количеству игр, так и по продажам.
Если рассматривать самые "отстающие" жанры:

  • по количеству: меньше всего игр в жанре Platform.
  • по продажам: самые низкие у жанра Adventure (довольно сильно отличаются от средних продаж)

Вывод¶

После исследовательского анализа данных можно сделать следующие выводы:

  • с каждым годом количество выпущенных игр увеличивается (наблюдался резкий подъем в 2008 году)
  • самыми прибыльными платформами (исходя из предоставленных данных) являются:
  • PlayStation 2
  • XBox 360
  • PlayStation 3
  • средний срок жизни платформы составляет 7 - 10 лет

Был определен актуальный период, за который стоит анализировать данные, готовясь к рекламной кампании в следующем (2017) году. Это период с 2013 по 2016 год. Определено, что:

  • потенциально прибыльными платформами являются PlayStation 4 и XBox One
  • большинство выходящих игр продается тиражом менее 0.8 мнл копий
  • оценки пользователей не имеют корреляции с продажами
  • корреляция оценок критиков и продаж выражена сильнее, чем корреляция с оценками пользователей, но всё же она выражена достаточно слабо
  • больше всего игр выпускается в жанрах:
  • Action
  • Misc
  • Sports
  • жанры, которые приносят стабильный доход:
  • Shooter
  • Sports
  • Platform

Портрет пользователя каждого региона¶

Популярность платформ по регионам¶

Рассмотрим популярность платформ в каждом из регионов:

In [53]:
region_pivot = (games_2013
                .pivot_table(index='platform', values=['na_sales', 'eu_sales', 'jp_sales'], aggfunc='sum')
                .reset_index())
region_pivot.columns = ['platform', 'Европа', 'Япония', 'Северная Америка']

fig = px.bar(region_pivot, x='platform', y=['Европа', 'Япония', 'Северная Америка'], barmode='group',
            labels={'platform': 'Платформа', 
                    'value': 'Продажи, млн копий',
                    'variable': 'Регион'},
             title="Популярность платформ по регионам")
fig.update_layout(xaxis={'categoryorder': 'total descending'})
fig.show()

В период с 2013 по 2016 год самыми популярными платформами:

  • для Северной Америки являются:
  • PlayStation 4
  • XBox One
  • XBox 360
  • PlayStation 3
  • Nintendo 3DS
  • для Европы:
  • PlayStation 4
  • PlayStation 3
  • XBox One
  • XBox 360
  • Nintendo 3DS
  • для Японии:
  • Nintendo 3DS
  • PlayStation 3
  • PlayStation Vita
  • PlayStation 4
  • WiiU

В Японии стараются поддерживать "своего" производителя, поэтому в топе платформ находятся "приставки" из Японии.
В Америке ситуация почти аналогичная, там поддерживают XBox, но есть и PlayStation (что может быть обусловлено относительно провальным стартом XBox One)
Европа взяла лучшие и популярные консоли из двух вышеуказанных регионов.

Популярность жанров по регионам¶

In [54]:
genre_pivot = (games_2013
                .pivot_table(index='genre', values=['na_sales', 'eu_sales', 'jp_sales'], aggfunc='sum')
                .reset_index())
genre_pivot.columns = ['genre', 'Европа', 'Япония', 'Северная Америка']

fig = px.bar(genre_pivot, x='genre', y=['Европа', 'Япония', 'Северная Америка'], barmode='group',
            labels={'genre': 'Жанр', 
                    'value': 'Продажи, млн копий',
                    'variable': 'Регион'},
             title="Популярность жанров по регионам")
fig.update_layout(xaxis={'categoryorder': 'total descending'})
fig.show()

В период с 2009 по 2016 год самыми популярными жанрами:

  • для Северной Америки являются:

  • Action

  • Shooter

  • Sports

  • Role-Playing (RPG)

  • Misc

  • для Европы:

  • Action

  • Shooter

  • Sports

  • Role-Playing (RPG)

  • Racing

  • для Японии:

  • Role-Plying (RPG)

  • Action

  • Misc

  • Fighting

  • Shooter

В Японии популярен жанр RPG. Но у японцев есть свой "поджанр" - JRPG. Он сильно отличается от западных RPG. Также в Японии популярны местные консоли, для которых JRPG игры и разрабатываются (в основном).
В Америке и Европе вкусы достаточно схожи. Action и Shooter - два жанра, в которых реакция и навыки решают всё, что позволяет ввести некую соревновательную составляющую (киберспорт и спидраны).

Влияние возрастного рейтинга на продажи в регионах¶

In [55]:
games_2013['rating'].value_counts(dropna=False)
Out[55]:
NaN     977
M       369
T       333
E       302
E10+    252
Name: rating, dtype: int64

Присутствует очень много пропусков в рейтинге. Заполним пропуски значением not_given:

In [56]:
games_2013['rating'] = games_2013['rating'].fillna('not_given')
In [57]:
genre_pivot = (games_2013
                .pivot_table(index='rating', values=['na_sales', 'eu_sales', 'jp_sales'], aggfunc='sum')
                .reset_index())
genre_pivot.columns = ['rating', 'Европа', 'Япония', 'Северная Америка']

fig = px.bar(genre_pivot, x='rating', y=['Европа', 'Япония', 'Северная Америка'], barmode='group',
            labels={'rating': 'Возрастной рейтинг', 
                    'value': 'Продажи, млн копий',
                    'variable': 'Регион'},
             title="Продажи игр разного возрастного рейтинга по регионам")
fig.update_layout(xaxis={'categoryorder': 'total descending'})
fig.show()

По диаграмме можно судить о том, что продажи игр в регионах не зависят от возрастного рейтинга игры.

В Северной Америке и Европе по продажам лидируют игры с рейтингом "Для взрослых" (шутеры, экшен вписываются в этот рейтинг).

В Японии же популярнее всего оказались игры с рейтингом, который не представлен в датасете. В Японии существует своя органициция по оценке игр - CERO. К тому же Японский рынок в большинстве своем очень "закрытый". Поэтому организиции ESRB (которая работает на Американский и Канадский рынки), нет смысла оценивать каждую игру, которая остается на Японском рынке (без выхода в другие регионы)

Вывод¶

Игрок из Северной Америки:

  • играет на консоли (XBox и PlayStation)
  • любит игры жанра Action и Shooter
  • предпочитает игры с возрастным рейтингом M (Для взрослых)

Игрок из Европы:

  • играет на консоли (PlayStation и XBox)
  • любит игры жанра Action и Shooter
  • предпочитает игры с возрастным рейтингом M (Для взрослых)

Игрок из Японии:

  • играет на консоли (Nintendo и PlayStation)
  • любит игры жанра RPG и Action
  • предпочитает игры со своего рынка, которые не были оценены ESRB

Проверка гипотез¶

Пользовательские рейтинги платформ Xbox One и PC¶

Проверка гипотезы: Средние пользовательские рейтинги платформ Xbox One и PC одинаковые

H_0: Пользовательская оценка (user_score) платформы Xbox One = Пользовательская оценка (`user_score`) платформы PC`
H_1: Пользовательская оценка (user_score) платформы Xbox One ≠ Пользовательская оценка (`user_score`) платформы PC`
alpha = 0.05
In [58]:
results = st.ttest_ind(games_2013.dropna().query('platform == "XOne"')['user_score'],
                       games_2013.dropna().query('platform == "PC"')['user_score'], equal_var=False)

alpha = .05

print(results.pvalue)

if results.pvalue < alpha:
    print('Отвергаем нулевую гипотезу')
else:
    print('Не получилось отвергнуть нулевую гипотезу')
0.1788264826340131
Не получилось отвергнуть нулевую гипотезу

Вероятность получить такую же оценку составляет ~ 20%. Вероятность достаточно большая, чтобы делать вывод о значительном различиями между средними оценками.

Средние пользовательские рейтинги платформ Xbox One и PC ~ одинаковые

Пользовательские рейтинги жанров Action и Sports¶

Проверка гипотезы: Средние пользовательские рейтинги жанров Action и Sports разные

H_0: Пользовательская оценка (user_score) жанра Action = Пользовательская оценка (`user_score`) жанра Sport`
H_1: Пользовательская оценка (user_score) жанра Action ≠ Пользовательская оценка (`user_score`) жанра Sport`
alpha = 0.05
In [59]:
results = st.ttest_ind(games_2013.dropna().query('genre == "Action"')['user_score'],
                       games_2013.dropna().query('genre == "Sports"')['user_score'], equal_var=False)

alpha = .05

print(results.pvalue)

if results.pvalue < alpha:
    print('Отвергаем нулевую гипотезу')
else:
    print('Не получилось отвергнуть нулевую гипотезу')
1.0496920005008586e-13
Отвергаем нулевую гипотезу

Вероятность получить такую же оценку составляет ~ 0%. Вероятность достаточно мала, следовательно средние пользовательские оценки не равны

Средние пользовательские рейтинги жанров Action и Sports разные

Общий вывод¶

В проекте была проделана работа по предобработке данных.

Были обнаружены пропуски в колонках с оценками и рейтингами. Возможно датасет стоило вернуть на доработку. Были проанализированы различные игровые платформы и жанры игр. Обнаружено, что:

  • с каждым годом количество выпущенных игр увеличивается (большинство игр выпускалось в период с 2013 по 2016 год)
  • за всё время больше всего продаж было на PlayStation 2, XBox 360 и PlayStation 3
  • средний срок жизни платформы составляет 7-10 лет
  • самыми новыми платформами являются:
  • Xbox One
  • PlayStation 4
  • в большинстве случаев суммарные продажи игр не превышают 0.8 млн проданных копий
  • корреляция продаж с от оценками критиков и пользователей выражена слабо (корреляция с оценками пользователей она практически отсутствует)

Был составлен портрет пользователя каждого из представленных регионов.

  • Игрок из Северной Америки:

  • играет на консоли (XBox и PlayStation)

  • любит игры жанра Action и Shooter

  • предпочитает игры с возрастным рейтингом M (Для взрослых)

  • Игрок из Европы:

  • играет на консоли (PlayStation и XBox)

  • любит игры жанра Action и Shooter

  • предпочитает игры с возрастным рейтингом M (Для взрослых)

  • Игрок из Японии:

  • играет на консоли (Nintendo и PlayStation)

  • любит игры жанра RPG и Action

  • предпочитает игры со своего рынка, которые не были оценены ESRB

Также обнаружено, что:

  • средние пользовательские оценки платформ Xbox One и PC ~ одинаковые
  • средние пользовательские оценки жанров Action и Sports сильно отличаются

Самыми перспективными платформами оказались PlayStation 4 и XBox One. Именно на них стоит делать ставку во время рекламной кампании на следующий год. Большее внимание стоит уледить платформе PlayStation 4

По жанрам стоит обратить внимание на Shooter, Sports и Platform (жанры для всех регионов).
Если же делать отдельные рекламные кампании для отдельных регионов, то лучше обращаться к портрету пользователя для выявления трендов региона.